package com.gdones.gpt.bus.activecode.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.gdones.common.core.dto.MyPageBand;
import com.gdones.common.core.dto.MyPager;
import com.gdones.common.core.dto.MyResult;
import com.gdones.gpt.bus.activecode.dto.ActiveCodeDto;
import com.gdones.gpt.bus.activecode.dto.GptActivationCode;
import com.gdones.gpt.bus.activecode.mapper.GptActivationCodeMapper;
import com.gdones.gpt.bus.activecode.service.IGptActivationCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdones.gpt.bus.gptstaff.dto.Staff;
import com.gdones.gpt.bus.gptstaff.dto.StaffModeGrant;
import com.gdones.gpt.bus.gptstaff.mapper.StaffInfoMapper;
import com.gdones.gpt.bus.gptstaff.mapper.StaffMapper;
import com.gdones.gpt.bus.gptstaff.mapper.StaffModeGrantMapper;
import com.gdones.gpt.bus.gptstaff.service.IStaffInfoService;
import com.gdones.gpt.bus.gptstaff.service.IStaffModeGrantService;
import com.gdones.gpt.bus.modes.dto.GptModes;
import com.gdones.gpt.bus.modetemplate.dto.GptTemplate;
import com.gdones.gpt.bus.modetemplate.dto.GptTemplateInfo;
import com.gdones.gpt.bus.modetemplate.mapper.GptTemplateInfoMapper;
import com.gdones.gpt.bus.modetemplate.mapper.GptTemplateMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author GaoJingBo
 * @since 2023-06-03
 */
@Service
@RefreshScope
@Transactional
public class GptActivationCodeServiceImpl extends ServiceImpl<GptActivationCodeMapper, GptActivationCode> implements IGptActivationCodeService {

    @Autowired
    private GptActivationCodeMapper activationCodeMapper;

    @Autowired
    private GptTemplateMapper gptTemplateMapper;

    @Autowired
    private GptTemplateInfoMapper gptTemplateInfoMapper;

    @Autowired
    private StaffMapper staffMapper;

    @Resource(name = "staffModeGrantServiceImpl")
    private IStaffModeGrantService staffModeGrantServiceImpl;

    @Autowired
    private StaffModeGrantMapper staffModeGrantMapper;

    @Resource(name = "staffInfoServiceImpl")
    private IStaffInfoService staffInfoServiceImpl;

    @Autowired
    private StaffInfoMapper staffInfoMapper;

    @Value("${mygpt.newStaffTyDay}")
    private String newStaffTyDay;

    @Override
    public MyResult pages(ActiveCodeDto dto, MyPageBand pageBand) {

        MyResult result = new MyResult();

        IPage<ActiveCodeDto> pages = activationCodeMapper.pages(PageDTO.of(pageBand.getPage(), pageBand.getSize()), dto);

        // 根据分页的结果封装返回数据
        MyPager<ActiveCodeDto> pager = new MyPager<>();
        pager.setTotal(pages.getTotal());
        pager.setPage(pageBand.getPage());
        pager.setPageSize(pageBand.getSize());
        pager.setRows(pages.getRecords());

        result.setData(pager);
        result.setMsg("查询成功！");

        return result;
    }

    @Override
    public MyResult mylist(ActiveCodeDto dto) {

        MyResult result = new MyResult();

        List<ActiveCodeDto> list = activationCodeMapper.myList(dto);

        result.setData(list);
        result.setMsg("查询成功！");

        return result;
    }

    @Override
    public MyResult getByID(String id) {

        MyResult result = new MyResult();

        ActiveCodeDto dto = activationCodeMapper.getByID(id);

        if(dto!=null){
            result.setMsg("查询成功！");
            result.setData(dto);
        }else{
            result.setMsg("查询失败！");
            result.setCode("9999");
        }

        return result;
    }

    @Override
    public MyResult staffActiveTheCode(GptActivationCode dto) {

        MyResult result = new MyResult();

        Staff staff = staffMapper.selectById(dto.getStaffID());
        if(staff==null){
            result.setMsg("激活出错：客户ID不存在。");
            result.setCode("9999");
            return result;
        }

        // 1.查询出激活码对应的卡
        QueryWrapper<GptActivationCode> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activeCode",dto.getActiveCode());

        List<GptActivationCode> list = this.list(queryWrapper);

        if(list.size()<=0){
            result.setMsg("激活码非法或不存在！");
            result.setCode("9999");
            return result;
        }

        // 2.验证激活码是否被使用
        GptActivationCode gptActivationCode = list.get(0);
        if(gptActivationCode.getStaffID()!=null){
            result.setMsg("激活码已被激活请勿重复激活！");
            result.setCode("9999");
            return result;
        }

        // 3. 查询激活码对应的模板信息

        // 3.1 查询模板信息
        GptTemplate gptTemplate = gptTemplateMapper.selectById(gptActivationCode.getTemplateID());
        if(gptTemplate==null){
            result.setMsg("激活出错：激活中未找到会员模板信息，请联系管理员！");
            result.setCode("9999");
            return result;
        }

        QueryWrapper<GptTemplateInfo> templateInfoQueryWrapper = new QueryWrapper<>();
        templateInfoQueryWrapper.eq("templateID",gptActivationCode.getTemplateID());

        List<GptTemplateInfo> templateInfos = gptTemplateInfoMapper.selectList(templateInfoQueryWrapper);
        if(templateInfos.size()<=0){
            result.setMsg("激活出错：激活中未找到会员模板明细，请联系管理员！");
            result.setCode("9999");
            return result;
        }

        // 判断激活方法
        if(staff.getStaffStateCode()==null){
            //结束时间
            long l = new Date().getTime() + (TimeUnit.DAYS.toMillis(gptActivationCode.getActiveDays()));
            staff.setVipEndTime(new Date(l));
        }else{
            Integer oldVipCode = Integer.valueOf(staff.getStaffStateCode());
            Integer newVipCode = Integer.valueOf(gptTemplate.getGptVipTypeCode());
            if(oldVipCode>newVipCode){
                result.setMsg("激活出错：您当前会员等级高，而您要激活的会员等级低，请在当前会员到期后再进行激活！");
                result.setCode("9999");
                return result;
            }
            //结束时间
            long l = staff.getVipEndTime().getTime() + (TimeUnit.DAYS.toMillis(gptActivationCode.getActiveDays()));
            staff.setVipEndTime(new Date(l));
        }

        // 4. 修改用户信息
        staff.setStaffStateCode(gptTemplate.getGptVipTypeCode());
        staff.setStaffStateName(gptTemplate.getGptVipTypeName());

        // 计算时间
        staff.setVipStartTime(new Date());

        staff.setVipIsCanUse("1");

        // 创建授权用户空模板集合
        List<StaffModeGrant> grantList = new LinkedList<>();
        for(GptTemplateInfo templateInfo:templateInfos){
            StaffModeGrant grantOne = new StaffModeGrant();
            grantOne.setModelsID(templateInfo.getModelsID());
            grantOne.setModelsName(templateInfo.getModelsName());
            grantOne.setIsHaveDayLimit(templateInfo.getIsHaveDayLimit());
            grantOne.setDayLimitCount(templateInfo.getDayLimitCount());
            grantOne.setUseLess(templateInfo.getDayLimitCount());
            grantOne.setTemplateID(gptActivationCode.getTemplateID());
            grantOne.setStaffID(staff.getStaffID());
            grantOne.setModeGrantUseTypeCode(templateInfo.getModeGrantUseTypeCode());
            grantOne.setModeGrantUseTypeName(templateInfo.getModeGrantUseTypeName());
            grantList.add(grantOne);
        }



        // 更新客户信息
        int i = staffMapper.updateById(staff);
        if(i<=0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.setMsg("激活出错：在用户激活过程中出错。");
            result.setCode("9999");
            return result;
        }

        // 添加授权信息
        int del = staffModeGrantMapper.realDeleteByStaffID(staff.getStaffID());
        boolean b = staffModeGrantServiceImpl.saveBatch(grantList);
        if(!b){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.setMsg("激活出错：在用户激活授权过程中出错。");
            result.setCode("9999");
            return result;
        }

        // 3.激活卡修改
        gptActivationCode.setStaffID(dto.getStaffID());
        gptActivationCode.setStaffName(dto.getStaffName());
        gptActivationCode.setActiveTime(new Date());
        // 修改激活卡信息
        boolean b2 = this.updateById(gptActivationCode);
        if(!b2){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.setMsg("激活出错：在用户激活激活卡过程中出错。");
            result.setCode("9999");
            return result;
        }

        // 激活成功-日志记录
        staffInfoServiceImpl.logForActive(staff.getStaffID(),staff.getUserName(),gptActivationCode.getActiveCode(),gptTemplate.getGptVipTypeName(),gptActivationCode.getActiveDays());

        result.setMsg("会员【"+gptTemplate.getGptVipTypeName()+"】激活成功，激活【"+gptActivationCode.getActiveDays()+"】天");

        return result;
    }

    @Override
    public MyResult deletes(String ids) {

        MyResult result = new MyResult();

        String[] split = ids.split(",");
        List<String> list = Arrays.asList(split);

        int i = activationCodeMapper.deleteBatchIds(list);

        if(i>0){
            result.setMsg("激活码删除成功！");
        }else{
            result.setMsg("激活码删除失败！");
            result.setCode("9999");
        }

        return result;
    }

    @Override
    public MyResult createAcitveCodes(ActiveCodeDto dto) {

        MyResult result = new MyResult();

        List<GptActivationCode> codeList = new LinkedList<>();

        for(int i=0;i<dto.getCreateCount();i++){
            GptActivationCode temp = new GptActivationCode();

            BeanUtils.copyProperties(dto,temp);
            // 生成激活码编号
            String carCode = IdUtil.randomUUID();
            temp.setActiveCode(carCode);
            codeList.add(temp);
        }

        // 添加
        boolean b = this.saveBatch(codeList);

        if(b){
            result.setMsg("创建激活卡成功！");
            result.setData(codeList);
        }else{
            result.setMsg("创建激活卡失败！");
            result.setCode("9999");
        }

        return result;
    }

    @Override
    public MyResult staffActiveTiYan(String staffID) {

        MyResult result = new MyResult();

        Staff staff = staffMapper.selectById(staffID);
        if(staff==null){
            result.setMsg("激活出错：客户ID不存在。");
            result.setCode("9999");
            return result;
        }

        if(staff.getActivationCode()!=null){
            result.setMsg("激活出错：已不是新用户不能激活新手体验卡。");
            result.setCode("9999");
            return result;
        }

        // 1. 先查询出新用户体验模板
        QueryWrapper<GptTemplate> templateQueryWrapper = new QueryWrapper<>();
        templateQueryWrapper.eq("isNewStaffTemplate","1");

        List<GptTemplate> templateList = gptTemplateMapper.selectList(templateQueryWrapper);
        if(templateList.size()<=0){// 没有模板
            result.setMsg("激活出错：管理员没有设置体验模板，请联系管理员。");
            result.setCode("9999");
            return result;
        }

        // 2.有模板则查询模板详情进行激活
        GptTemplate template = templateList.get(0);
        QueryWrapper<GptTemplateInfo> templateInfoQueryWrapper = new QueryWrapper<>();
        templateInfoQueryWrapper.eq("templateID", template.getTemplateID());
        List<GptTemplateInfo> templateInfos = gptTemplateInfoMapper.selectList(templateInfoQueryWrapper);

        // 创建授权用户空模板集合
        List<StaffModeGrant> grantList = new LinkedList<>();
        for(GptTemplateInfo templateInfo:templateInfos){
            StaffModeGrant grantOne = new StaffModeGrant();
            grantOne.setModelsID(templateInfo.getModelsID());
            grantOne.setModelsName(templateInfo.getModelsName());
            grantOne.setIsHaveDayLimit(templateInfo.getIsHaveDayLimit());
            grantOne.setDayLimitCount(templateInfo.getDayLimitCount());
            grantOne.setUseLess(templateInfo.getDayLimitCount());
            grantOne.setTemplateID(template.getTemplateID());
            grantOne.setStaffID(staffID);
            grantOne.setModeGrantUseTypeCode(templateInfo.getModeGrantUseTypeCode());
            grantOne.setModeGrantUseTypeName(templateInfo.getModeGrantUseTypeName());
            grantList.add(grantOne);
        }

        // 设置用户信息-会员信息
        staff.setStaffStateCode(template.getGptVipTypeCode());
        staff.setStaffStateName(template.getGptVipTypeName());
        // 计算时间
        staff.setVipStartTime(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, Integer.valueOf(newStaffTyDay));
        Date date = calendar.getTime();
        long milliseconds = date.getTime();
        staff.setVipEndTime(new Date(milliseconds));
        staff.setVipIsCanUse("1");

        // 更新客户信息
        int i = staffMapper.updateById(staff);
        if(i<=0){
            result.setMsg("激活出错：在用户激活过程中出错。");
            result.setCode("9999");
            return result;
        }
        // 添加授权信息
        int del = staffModeGrantMapper.realDeleteByStaffID(staffID);
        boolean b = staffModeGrantServiceImpl.saveBatch(grantList);
        if(!b){
            result.setMsg("激活出错：在用户激活授权过程中出错。");
            result.setCode("9999");
            return result;
        }

        // 激活成功-日志记录
        staffInfoServiceImpl.logForTiyanActive(staff.getStaffID(),staff.getUserName());

        result.setMsg("体验版激活成功，激活体验【"+newStaffTyDay+"】天");
        
        return result;
    }
}
